package com.cmeduSystem.common.flow.cmd;

import lombok.AllArgsConstructor;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.api.variable.VariableContainer;
import org.flowable.common.engine.impl.el.VariableContainerWrapper;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.runtime.Execution;
import org.flowable.variable.api.history.HistoricVariableInstance;

import java.util.*;

/**
 * EL表达式解析和执行的命令。
 *
 * @author xulei
 * @date 2025-09-04
 */
@AllArgsConstructor
public class ExpressionCmd implements Command<Object> {

    private String processInstanceId;
    private String executionId;
    private String exp;

    @Override
    public Object execute(CommandContext commandContext) {
        ProcessEngineConfigurationImpl cfg = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        Expression expression = cfg.getExpressionManager().createExpression(exp);
        Execution execution = cfg.getRuntimeService().createExecutionQuery().executionId(executionId).singleResult();
        Map<String, Object> variables;
        if (execution != null) {
             variables = cfg.getRuntimeService().getVariables(executionId);
        } else {
            List<HistoricVariableInstance> variableInstances =
                    cfg.getHistoryService().createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).list();
            variables = new HashMap<>(variableInstances.size());
            for (HistoricVariableInstance variableInstance : variableInstances) {
                variables.put(variableInstance.getVariableName(), variableInstance.getValue());
            }
        }
        VariableContainer variableContainer = new VariableContainerWrapper(variables);
        return cfg.getManagementService().executeCommand(cc -> expression.getValue(variableContainer));
    }
}
